package com.example.fireassistant_server.service.impl;


import com.example.fireassistant_server.dto.file.FileDto;
import com.example.fireassistant_server.dto.file.FileUploadRequest;
import com.example.fireassistant_server.entity.*;
import com.example.fireassistant_server.enums.FileStatus;
import com.example.fireassistant_server.enums.Storage;
import com.example.fireassistant_server.exception.BizException;
import com.example.fireassistant_server.exception.ExceptionType;
import com.example.fireassistant_server.mapper.FileMapper;
import com.example.fireassistant_server.repository.*;
import com.example.fireassistant_server.service.FileService;
import com.example.fireassistant_server.service.StorageService;
import com.example.fireassistant_server.utils.FileTypeTransformer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Map;
import java.util.Optional;

@Service
public class FileServiceImpl implements FileService {

    private FileRepository fileRepository;

    private Map<String, StorageService> storageServices;

    private FileMapper mapper;


    private HydrantFilesRepository hydrantFilesRepository;

    private CircleFilesRepository circleFilesRepository;

    private GonFilesRepository gonFilesRepository;

    private LineFilesRepository lineFilesRepository;

    private CompanyFilesRepository companyFilesRepository;

    private PoiFilesRepository poiFilesRepository;


    @Override
    public TmpSecret getTmpSecret() throws IOException {
        //通过接口获取STS令牌  在前端上传文件至存储桶
        return storageServices.get(getDefaultStorage().name()).initFileUpload();
    }

    @Override
    @Transactional
    public FileDto initUpload(FileUploadRequest fileUploadRequest) {
        //创建File实体
        File file = mapper.createEntity(fileUploadRequest);
        file.setStorage(getDefaultStorage());
        file.setType(FileTypeTransformer.getFileTypeFromExt(fileUploadRequest.getExt()));
        File SavedFile = fileRepository.save(file);
        if (fileUploadRequest.getObject_type()!=null){
            switch (fileUploadRequest.getObject_type()){
                case "hydrant":
                    //更新hydrant_file
                    HydrantFiles hydrantFiles = new HydrantFiles();
                    hydrantFiles.setFileId(SavedFile.getId());
                    hydrantFiles.setHydrantId(fileUploadRequest.getObject_id());
                    hydrantFilesRepository.save(hydrantFiles);
                    break;
                case "circle":
                    System.out.println("circle");
                    CircleFiles circleFiles = new CircleFiles();
                    circleFiles.setFileId(SavedFile.getId());
                    circleFiles.setCircleId(fileUploadRequest.getObject_id());
                    circleFilesRepository.save(circleFiles);
                    break;
                case "polyLine":
                    System.out.println("polyLine");
                    LineFiles lineFiles = new LineFiles();
                    lineFiles.setFileId(SavedFile.getId());
                    lineFiles.setLineId(fileUploadRequest.getObject_id());
                    lineFilesRepository.save(lineFiles);
                    break;
                case "polyGon":
                    System.out.println("polyGon");
                    GonFiles gonFiles = new GonFiles();
                    gonFiles.setFileId(SavedFile.getId());
                    gonFiles.setGonId(fileUploadRequest.getObject_id());
                    gonFilesRepository.save(gonFiles);
                    break;
                case "company":
                    System.out.println("company");
                    CompanyFiles companyFiles = new CompanyFiles();
                    companyFiles.setFileId(SavedFile.getId());
                    companyFiles.setCompanyId(fileUploadRequest.getObject_id());
                    companyFilesRepository.save(companyFiles);
                    break;
                case "poi":
                    System.out.println("POI");
                    PoiFiles poiFiles = new PoiFiles();
                    poiFiles.setFileId(SavedFile.getId());
                    poiFiles.setPoiId(fileUploadRequest.getObject_id());
                    poiFilesRepository.save(poiFiles);
                default:
                    System.out.println("user");
            }
        }
        return mapper.toDto(file);
    }


    @Override
    public FileDto finishUpload(String id) {
        Optional<File> fileOptional = fileRepository.findById(id);
        if (!fileOptional.isPresent()) {
            throw new BizException(ExceptionType.FILE_NOT_FOUND);
        }
        //Todo:只有上传者才能更新finish;权限判断
        //TODO：验证远程文件是否存在

        File file = fileOptional.get();
        file.setStatus(FileStatus.UPLOADED);
        return mapper.toDto(fileRepository.save(file));
    }

    public File getById(String id){
        Optional<File> file = fileRepository.findById(id);
        if (!file.isPresent()) {
            throw new BizException(ExceptionType.FILE_NOT_FOUND);
        }
        return fileRepository.save(file.get());
    }
    //Todo:后台设置当前Storage
    public Storage getDefaultStorage() {
        return Storage.COS;
    }


    @Override
    @Transactional
    public void delete(String type, String id) {
        // 先删除对应的连接表
        switch (type) {
            case "hydrant":
                hydrantFilesRepository.deleteByFileId(id);
                break;
            case "circle":
                circleFilesRepository.deleteByFileId(id);
                break;
            case "polyLine":
                lineFilesRepository.deleteByFileId(id);
                break;
            case "polyGon":
                gonFilesRepository.deleteByFileId(id);
                break;
            case "company":
                companyFilesRepository.deleteByFileId(id);
                break;
            case "poi":
                poiFilesRepository.deleteByFileId(id);
                break;
            default:
                System.out.println("user default");
        }
        // 删除文件
        Optional<File> file = fileRepository.findById(id);
        if (!file.isPresent()) {
            throw new BizException(ExceptionType.FILE_NOT_FOUND);
        }
        fileRepository.deleteById(id);
    }

    @Override
    public void deleteById(String id) {
        // 删除文件
        Optional<File> file = fileRepository.findById(id);
        if (!file.isPresent()) {
            throw new BizException(ExceptionType.FILE_NOT_FOUND);
        }
        fileRepository.deleteById(id);
    }


    @Autowired
    public void setFileRepository(FileRepository fileRepository) {
        this.fileRepository = fileRepository;
    }

    @Autowired
    public void setStorageServices(Map<String, StorageService> storageServices) {
        this.storageServices = storageServices;
    }

    @Autowired
    public void setMapper(FileMapper mapper) {
        this.mapper = mapper;
    }

    @Autowired
    public void setCircleFilesRepository(CircleFilesRepository circleFilesRepository) {
        this.circleFilesRepository = circleFilesRepository;
    }

    @Autowired
    public void setCompanyFilesRepository(CompanyFilesRepository companyFilesRepository) {
        this.companyFilesRepository = companyFilesRepository;
    }

    @Autowired
    public void setGonFilesRepository(GonFilesRepository gonFilesRepository) {
        this.gonFilesRepository = gonFilesRepository;
    }

    @Autowired
    public void setLineFilesRepository(LineFilesRepository lineFilesRepository) {
        this.lineFilesRepository = lineFilesRepository;
    }

    @Autowired
    public void setHydrantFilesRepository(HydrantFilesRepository hydrantFilesRepository) {
        this.hydrantFilesRepository = hydrantFilesRepository;
    }

    @Autowired
    public void setPoiFilesRepository(PoiFilesRepository poiFilesRepository) {
        this.poiFilesRepository = poiFilesRepository;
    }
}
